package cc.vv.party.config

import cc.vv.party.common.security.SessionInvalidSecurityInterceptor
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.converter.StringHttpMessageConverter
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
import java.nio.charset.Charset
import java.text.SimpleDateFormat

/**
 * @version 1.0.0
 * @author: Gyb
 * @date 2018/8/9
 * @description
 **/

@Configuration
class WebConfig : WebMvcConfigurationSupport() {

    @Value("\${interceptor.exclude-patterns}")
    lateinit var excludePatterns: Array<String>

    @Bean
    fun responseBodyConverter(): HttpMessageConverter<String> {
        return StringHttpMessageConverter(Charset.forName("UTF-8"))
    }

    override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) {
        converters.add(this.responseBodyConverter())
        val jackson2HttpMessageConverter = MappingJackson2HttpMessageConverter()
        val objectMapper = ObjectMapper()
        val simpleModule = SimpleModule()
        simpleModule.addSerializer(Long::class.java, ToStringSerializer.instance)
        simpleModule.addSerializer(java.lang.Long.TYPE, ToStringSerializer.instance)
        objectMapper.registerModule(simpleModule)
        objectMapper.dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        jackson2HttpMessageConverter.objectMapper = objectMapper
        jackson2HttpMessageConverter.supportedMediaTypes = mutableListOf(MediaType.APPLICATION_JSON_UTF8,MediaType.TEXT_HTML)
        val stringHttpMessageConverter = StringHttpMessageConverter()
        stringHttpMessageConverter.supportedMediaTypes = mutableListOf(MediaType.APPLICATION_JSON_UTF8,MediaType.TEXT_HTML)
        converters.add(stringHttpMessageConverter)
        converters.add(jackson2HttpMessageConverter)
        super.configureMessageConverters(converters)
    }

    override fun configureContentNegotiation(configurer: ContentNegotiationConfigurer) {
        configurer.favorPathExtension(false)
    }

    /**
     * 解决URL转发（资源地址映射）
     * @param registry
     */
    override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
        //和页面有关的静态目录都放在项目的static目录下
        registry.addResourceHandler("/static/**")
            .addResourceLocations("classpath:/static/")
        registry.addResourceHandler("swagger-ui.html")
            .addResourceLocations("classpath:/META-INF/resources/")
        registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/")
        super.addResourceHandlers(registry)
    }

    override fun addInterceptors(registry: InterceptorRegistry) {
        registry.addInterceptor(SessionInvalidSecurityInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns(*excludePatterns)
    }

}